package com.atguigu.yygh.user.service.impl;

import com.atguigu.yygh.common.handler.YyghException;
import com.atguigu.yygh.common.utils.JwtHelper;
import com.atguigu.yygh.enums.AuthStatusEnum;
import com.atguigu.yygh.model.user.Patient;
import com.atguigu.yygh.model.user.UserInfo;
import com.atguigu.yygh.user.mapper.UserInfoMapper;
import com.atguigu.yygh.user.service.PatientService;
import com.atguigu.yygh.user.service.UserInfoService;
import com.atguigu.yygh.vo.user.LoginVo;
import com.atguigu.yygh.vo.user.UserAuthVo;
import com.atguigu.yygh.vo.user.UserInfoQueryVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

//import org.springframework.data.domain.Page;

/**
 * @author 杨林
 * @create 2022-11-10 14:17 星期四
 * description:
 */
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper,UserInfo> implements UserInfoService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private PatientService patientService;

    //用户登录 返回name + token
    @Override
    public Map<String, Object> login(LoginVo loginVo) {
        String openid = loginVo.getOpenid();
        if (StringUtils.isEmpty(openid)){
            return this.loginByCodeAndPhone(loginVo);
        }else{
            return this.wxBoundingPhone(loginVo);
        }
    }

    //根据openid从mysql数据库中查询数据
    @Override
    public UserInfo selectWxInfoByOpenId(String openid) {

        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("openid", openid);
        UserInfo userInfo = userInfoMapper.selectOne(queryWrapper);

        return userInfo;
    }


    //用户认证
    @Override
    public void userAuth(long userId, UserAuthVo userAuthVo) {
        //根据用户id 查询用户信息
        UserInfo userInfo = userInfoMapper.selectById(userId);

        //设置认证信息
        userInfo.setName(userAuthVo.getName());
        userInfo.setCertificatesType(userAuthVo.getCertificatesType());
        userInfo.setCertificatesNo(userAuthVo.getCertificatesNo());
        userInfo.setCertificatesUrl(userAuthVo.getCertificatesUrl());

        //设置认证状态 -- 认证中  0---》1
        userInfo.setAuthStatus(AuthStatusEnum.AUTH_RUN.getStatus());  //0:表示未认证  1：表示认证中  2：表示认证完成

        //进行信息更行（根据id跟新）
        userInfoMapper.updateById(userInfo);

    }


    //根据条件  对用户列表进行分页查询
    @Override
    public IPage<UserInfo> selectPage(Page<UserInfo> pageParam, UserInfoQueryVo userInfoQueryVo) {

        String name = userInfoQueryVo.getKeyword(); //用于模糊匹配的用户名称
        Integer status = userInfoQueryVo.getStatus();  //用户的状态
        Integer authStatus = userInfoQueryVo.getAuthStatus();  //用户的认证状态
        String createTimeBegin = userInfoQueryVo.getCreateTimeBegin(); //开始时间
        String createTimeEnd = userInfoQueryVo.getCreateTimeEnd();  //结束时间

        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(name)){
            queryWrapper.like("name", name).or().eq("phone", name);
        }
        if (!StringUtils.isEmpty(status)){
            queryWrapper.eq("status", status);
        }
        if (!StringUtils.isEmpty(authStatus)){
            queryWrapper.eq("auth_status", authStatus);
        }
        if (!StringUtils.isEmpty(createTimeBegin)){
            queryWrapper.ge("create_time", createTimeBegin);
        }
        if (!StringUtils.isEmpty(createTimeEnd)){
            queryWrapper.le("create", createTimeEnd);
        }
        IPage<UserInfo> pages = userInfoMapper.selectPage(pageParam, queryWrapper);
        List<UserInfo> records = pages.getRecords();
        for (UserInfo record : records) {
            this.packUserInfo(record);
        }
        return pages;
    }

    /**
     * 用户锁定
     * @param userId
     * @param status  0：锁定  1：正常
     */
    @Override
    public void lock(Long userId, Integer status) {
        if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(status)){
            throw new YyghException(20001, "参数不能为空");
        }
        if (status == 1 || status == 0){
            QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("id", userId);
            UserInfo userInfo = userInfoMapper.selectOne(queryWrapper);
            userInfo.setStatus(status);
            userInfoMapper.updateById(userInfo);
        }
    }

    /**
     * 查询用户详情 (包括用户信息和用户所属的就诊人信息)
     * @param userId
     * @return
     */
    @Override
    public Map<String, Object> show(Long userId) {
        if (StringUtils.isEmpty(userId)){
            throw new YyghException(20001, "用户id不能为空");
        }
        UserInfo userInfo = this.getById(userId);
        this.packUserInfo(userInfo);
        Map<String,Object> map = new HashMap<>();
        map.put("userInfo", userInfo);

        //根据userId查询所属的就诊人信息
        List<Patient> patientList = patientService.findListByUserId(userId);
        map.put("patientList", patientList);
        return map;
    }

    /**
     * 认证审核
     * @param userId
     * @param authStatus  2:认证通过  -1：认证失败  1：审核中
     */
    @Override
    public void approval(long userId, Integer authStatus) {
        if (StringUtils.isEmpty(userId)){
            throw new YyghException(20001, "用户id不能为空");
        }

        if (authStatus.intValue() == 2 || authStatus.intValue() == -1){
            //根据userId获取userInfo
            UserInfo userInfo = this.getById(userId);
            userInfo.setAuthStatus(authStatus);
            userInfoMapper.updateById(userInfo);
        }
    }

    private void packUserInfo(UserInfo userInfo) {
        //封装认证状态
        Integer authStatus = userInfo.getAuthStatus();
        userInfo.getParam().put("authStatusString", AuthStatusEnum.getStatusNameByStatus(authStatus));
        //封装用户状态
        Integer status = userInfo.getStatus();
        String statusString = status.intValue() == 0 ? "锁定":"正常";
        userInfo.getParam().put("statusString", statusString);
    }

    private Map<String,Object> loginByCodeAndPhone(LoginVo loginVo){
        //1.获取手机号 + 验证码
        String code = loginVo.getCode(); //验证码
        String phone = loginVo.getPhone(); //手机号

        //2.校验参数
        if (StringUtils.isEmpty(code) || StringUtils.isEmpty(phone)){
            throw new YyghException(20001,"参数不能为空");
        }

        //3.校验短信验证码 校验失败则抛出异常 （无密登录）
        //3.1从redis中获取验证码
        String redis_code = redisTemplate.boundValueOps(phone).get();
        //判断用户输入的验证码是否与Redis中保存的验证码相同
        if (!redis_code.equals(code)){
            throw new YyghException(20001, "验证码不正确！！！");
        }

        //判断openid是否为空  如果为空手机验证码登录  如果不为空微信绑定手机号
        //获取openid
        String openid = loginVo.getOpenid();

        //4.判断手机号是否已被注册
        //4.1通过查询数据库 获取手机号
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("phone", phone);
        UserInfo userInfo = userInfoMapper.selectOne(queryWrapper);

        //5.未被注册 则自动注册
        if (userInfo == null){
            //注册用户
            userInfo = new UserInfo();
            userInfo.setPhone(phone);
            userInfo.setStatus(1); //0:表示锁定 1：表示正常
            //将新用户写入数据库中
            userInfoMapper.insert(userInfo);
        }

        //6.判断用户是否已被禁用
        Integer status = userInfo.getStatus();
        if (status == 0){
            throw new YyghException(20001, "该用户已被锁定");
        }

        //7.返回name + token
        //token:令牌  表示当前用户的身份
        Map<String,Object> map = new HashMap<>();
        String name = userInfo.getName();
        if (StringUtils.isEmpty(name)){
            //如果用户名为空 显示微信昵称
            name = userInfo.getNickName();
            if (StringUtils.isEmpty(name)){
                //如果用户名和微信名同时为空 则显示手机号
                name = userInfo.getPhone();
            }
        }
        String token = JwtHelper.createToken(userInfo.getId(), name);
        map.put("name", name);
        map.put("token", token);
        return map;
    }

    private Map<String,Object> wxBoundingPhone(LoginVo loginVo){
        //根据手机号查询，表中是否有与手机号相同的数据
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", loginVo.getPhone());
        UserInfo userInfo_phone = userInfoMapper.selectOne(queryWrapper);
        UserInfo userInfo_wx = this.selectWxInfoByOpenId(loginVo.getOpenid());


        if (userInfo_phone == null){  //说明表中不存在与绑定手机号相同的数据
            //将要绑定手机号放入userInfo_wx
            userInfo_wx.setPhone(loginVo.getPhone());
            //更新
            userInfoMapper.updateById(userInfo_wx);
        }else{
            //说明表中存在与要绑定手机号相同的手机号
            //此时  需要将两条手机号相同的数据合并为一条
            userInfo_wx.setPhone(userInfo_phone.getPhone());
            userInfo_wx.setCertificatesType(userInfo_phone.getCertificatesType());
            userInfo_wx.setCertificatesNo(userInfo_phone.getCertificatesNo());
            userInfo_wx.setCertificatesUrl(userInfo_phone.getCertificatesUrl());

            String phone = userInfo_phone.getPhone();
            QueryWrapper<UserInfo> objectQueryWrapper = new QueryWrapper<>();
            objectQueryWrapper.eq("phone", phone);
            //删除手机号数据
            userInfoMapper.delete(objectQueryWrapper);

            //添加新数据
            userInfoMapper.insert(userInfo_wx);
        }
        Map<String,Object> map = new HashMap<>();
        String token = JwtHelper.createToken(userInfo_wx.getId(), userInfo_wx.getName());
        map.put("token", token);
        String name = userInfo_wx.getName();
        if (StringUtils.isEmpty(name)){
            name = userInfo_wx.getNickName();
            if (StringUtils.isEmpty(name)){
                name = userInfo_wx.getPhone();
            }
        }
        map.put("name", name);
        return map;
    }
}
